package com.qlslylq.ad.sdk.core.loader;

import android.app.Activity;
import android.view.View;

import com.bytedance.sdk.openadsdk.AdSlot;
import com.bytedance.sdk.openadsdk.TTAdDislike;
import com.bytedance.sdk.openadsdk.TTAdLoadType;
import com.bytedance.sdk.openadsdk.TTAdNative;
import com.bytedance.sdk.openadsdk.TTNativeExpressAd;
import com.kwad.sdk.api.KsAdVideoPlayConfig;
import com.kwad.sdk.api.KsFeedAd;
import com.kwad.sdk.api.KsLoadManager;
import com.kwad.sdk.api.KsScene;
import com.mbridge.msdk.MBridgeConstans;
import com.mbridge.msdk.out.Campaign;
import com.mbridge.msdk.out.Frame;
import com.mbridge.msdk.out.MBNativeHandler;
import com.mbridge.msdk.out.NativeListener;
import com.qlslylq.ad.sdk.config.CsjMgrHolder;
import com.qlslylq.ad.sdk.config.KsMgrHolder;
import com.qlslylq.ad.sdk.constant.UrlConst;
import com.qlslylq.ad.sdk.core.ad.BaseAd;
import com.qlslylq.ad.sdk.core.ad.SingleFeedAd;
import com.qlslylq.ad.sdk.core.listener.FeedAdListener;
import com.qlslylq.ad.sdk.core.mgr.PoolMgr;
import com.qlslylq.ad.sdk.core.rsp.AdError;
import com.qlslylq.ad.sdk.enums.AdEventSign;
import com.qlslylq.ad.sdk.enums.AdPlatformEnum;
import com.qlslylq.ad.sdk.enums.ErrorEnum;
import com.qlslylq.ad.sdk.model.req.UserBehaviorAddDTO;
import com.qlslylq.ad.sdk.model.rsp.AdPlaceWebConfigureVO;
import com.qlslylq.ad.sdk.net.api.ApiServiceImpl;
import com.qlslylq.ad.sdk.util.DecimalUtils;
import com.qlslylq.ad.sdk.util.DensityUtils;
import com.qlslylq.ad.sdk.util.DeviceUtil;
import com.qlslylq.ad.sdk.util.GsonUtils;
import com.qlslylq.ad.sdk.util.Log;
import com.qq.e.ads.cfg.VideoOption;
import com.qq.e.ads.nativ.ADSize;
import com.qq.e.ads.nativ.NativeExpressAD;
import com.qq.e.ads.nativ.NativeExpressADView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.mbridge.msdk.MBridgeConstans.NATIVE_VIDEO_SUPPORT;

/**
 * 信息流广告加载器<br/>
 */
public class FeedAdLoader extends AdLoader<FeedAdListener> {

    //穿山甲期望宽度(默认：屏幕宽px)
    private float expressWidth;

    //穿山甲期望宽度(默认：0,即自适应,px)
    private float expressHeight;

    //加载数量(默认：1)
    private int adCount;

    //声音策略(默认策略：放音)
    private boolean autoPlayMuted;

    public FeedAdLoader(Activity context, long posId, FeedAdListener adListener) {
        this(context, posId, 0, 0, 1, false, adListener);
    }

    public FeedAdLoader(Activity context, long posId, float expressWidth, float expressHeight, int adCount, boolean autoPlayMuted, FeedAdListener adListener) {
        super(context, posId, adListener);
        if (expressWidth <= 0) {
            expressWidth = DeviceUtil.getScreenWidth(context);
        }
        if (expressHeight < 0) {
            expressHeight = 0;
        }
        if (adCount < 1) {
            adCount = 1;
        }
        this.expressWidth = expressWidth;
        this.expressHeight = expressHeight;
        this.adCount = adCount;
        this.autoPlayMuted = autoPlayMuted;
    }

    /**
     * 加载并展示<br/>
     */
    protected void load(AdPlaceWebConfigureVO config) {
        AdPlatformEnum platform = config.getPlatform();
        String posId = config.getPositionId();

        if (platform == AdPlatformEnum.PLATFORM_CSJ) {//穿山甲
            AdSlot adSlot = new AdSlot.Builder()
                    .setCodeId(posId)
                    .setExpressViewAcceptedSize(DensityUtils.px2dp(context, expressWidth), DensityUtils.px2dp(context, expressHeight))//dp。高度设置为0，则高度会自适应
                    .setAdLoadType(TTAdLoadType.PRELOAD)//[实时加载，预加载]
                    .setAdCount(adCount)
                    .build();
            CsjMgrHolder.createAdNative(context).loadNativeExpressAd(adSlot, new TTAdNative.NativeExpressAdListener() {
                public void onNativeExpressAdLoad(List<TTNativeExpressAd> list) {
                    List<SingleFeedAd> ads = new ArrayList<>();
                    if (list != null) {
                        list.forEach(item -> {
                            if (item != null) {
                                ads.add(new SingleFeedAd(item, platform));
                            }
                        });
                        if (!ads.isEmpty()) {
                            PoolMgr.getInstance().push(ads, config);
                        }
                    }

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, FeedAdLoader.super.posId));
                }

                public void onError(int code, String msg) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, code, msg)));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, code, msg));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, FeedAdLoader.super.posId));
                }
            });
        } else if (platform == AdPlatformEnum.PLATFORM_YLH) {//优量汇
            float expressWidthDp = DensityUtils.px2dp(context, expressWidth);
            float expressHeightDp = DensityUtils.px2dp(context, expressHeight);
            ADSize adSize = new ADSize((int) expressWidthDp, expressHeightDp == 0 ? ADSize.AUTO_HEIGHT : (int) expressHeightDp);
            NativeExpressAD ad = new NativeExpressAD(context, adSize, posId, new NativeExpressAD.NativeExpressADListener() {
                private List<SingleFeedAd> ads = new ArrayList<>();

                public void onADLoaded(List<NativeExpressADView> list) {
                    if (list != null) {
                        list.forEach(item -> {
                            if (item != null) {
                                ads.add(new SingleFeedAd(item, platform));
                            }
                        });
                        if (!ads.isEmpty()) {
                            PoolMgr.getInstance().push(ads, config);
                        }
                    }

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, FeedAdLoader.super.posId));
                }

                public void onRenderSuccess(NativeExpressADView adView) {

                }

                public void onADExposure(NativeExpressADView adView) {
                    Log.dp(String.format("曝光成功：%s", platform.getId()));
                    onAdShowSafety();
                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, FeedAdLoader.super.posId));
                }

                public void onADLeftApplication(NativeExpressADView adView) {

                }

                public void onADClosed(NativeExpressADView adView) {//关闭单个广告
//                    ((ViewGroup) adView.getParent()).removeView(adView);
                    for (int i = 0, size = ads.size(); i < size; i++) {
                        if (ads.get(i).getAd() == adView) {
                            getAdListener().onAdDismiss(ads.get(i));
                            break;
                        }
                    }

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLOSE, FeedAdLoader.super.posId));
                }

                public void onADClicked(NativeExpressADView adView) {
                    for (int i = 0, size = ads.size(); i < size; i++) {
                        if (ads.get(i).getAd() == adView) {
                            getAdListener().onAdClick(ads.get(i));
                            break;
                        }
                    }

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, FeedAdLoader.super.posId));
                }

                public void onRenderFail(NativeExpressADView adView) {
                    Log.e(GsonUtils.gsonString(ErrorEnum.ERR_RENDER.rsp(platform, adType)));
                    onAdShowErrorSafety(ErrorEnum.ERR_RENDER.rsp(platform, adType), platform, false);
                }

                public void onNoAD(com.qq.e.comm.util.AdError error) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, error.getErrorCode(), error.getErrorMsg())));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, error.getErrorCode(), error.getErrorMsg()));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, FeedAdLoader.super.posId));
                }
            });
            VideoOption option = new VideoOption.Builder()
                    .setAutoPlayMuted(autoPlayMuted)//声音策略
                    .setAutoPlayPolicy(VideoOption.AutoPlayPolicy.ALWAYS)//非WiFi环境下的声音策略
                    .setDetailPageMuted(false)
                    .build();
            ad.setVideoOption(option);
            ad.loadAD(adCount);
        } else if (platform == AdPlatformEnum.PLATFORM_KS) {//快手联盟
            KsScene scene = new KsScene.Builder(DecimalUtils.parseLongSafe(posId))
                    .setBackUrl(UrlConst.BACK_URL_AD) // scheme逆向唤醒协议名设置，与清单中所注册的协议名保持一致即可
                    .width((int) expressWidth)
                    .height((int) expressHeight)
                    .adNum(adCount)
                    .build();
            KsMgrHolder.get().loadConfigFeedAd(scene, new KsLoadManager.FeedAdListener() {
                public void onFeedAdLoad(List<KsFeedAd> list) {
                    List<SingleFeedAd> ads = new ArrayList<>();
                    if (list != null) {
                        list.forEach(item -> {
                            if (item != null) {
                                ads.add(new SingleFeedAd(item, platform));
                            }
                        });
                        if (!ads.isEmpty()) {
                            PoolMgr.getInstance().push(ads, config);
                        }
                    }

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, FeedAdLoader.super.posId));
                }

                public void onError(int code, String msg) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, code, msg)));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, code, msg));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, FeedAdLoader.super.posId));
                }
            });
        } else if (platform == AdPlatformEnum.PLATFORM_MINTEGRAL) {
            Map<String, Object> properties = MBNativeHandler.getNativeProperties(null, posId);
            properties.put(MBridgeConstans.NATIVE_VIDEO_WIDTH, expressWidth);
            properties.put(MBridgeConstans.NATIVE_VIDEO_HEIGHT, expressHeight == 0 ? 480 : expressHeight);
            properties.put(NATIVE_VIDEO_SUPPORT, true);
            properties.put(MBridgeConstans.PROPERTIES_AD_NUM, adCount);

            MBNativeHandler ad = new MBNativeHandler(properties, context);
            ad.setAdListener(new NativeListener.NativeAdListener() {

                List<SingleFeedAd> ads = new ArrayList<>();

                public void onAdLoaded(List<Campaign> list, int template) {
                    if (list != null) {
                        list.forEach(item -> {
                            if (item != null) {
                                Map<String, Object> extra = new HashMap<>();
                                extra.put(SingleFeedAd.KEY_HANDLER, ad);
                                ads.add(new SingleFeedAd(item, platform, extra));
                            }
                        });
                        if (!ads.isEmpty()) {
                            PoolMgr.getInstance().push(ads, config);
                        }
                    }

                    getAdListener().onAdLoad();

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_SUCCESS, FeedAdLoader.super.posId));
                }

                public void onAdLoadError(String msg) {
                    Log.e(GsonUtils.gsonString(AdError.build(platform, adType, ErrorEnum.ERR_LOAD_FAILD.getId(), msg)));
                    getAdListener().onAdLoadError(AdError.build(platform, adType, ErrorEnum.ERR_LOAD_FAILD.getId(), msg));

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_RETURN_FAIL, FeedAdLoader.super.posId));
                }

                public void onAdClick(Campaign campaign) {
                    SingleFeedAd result = null;
                    for (SingleFeedAd item : ads) {
                        if (item.getAd() == campaign) {
                            result = item;
                            break;
                        }
                    }
                    getAdListener().onAdClick(result);

                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, FeedAdLoader.super.posId));
                }

                public void onAdFramesLoaded(List<Frame> list) {

                }

                public void onLoggingImpression(int adsourceType) {
                    Log.dp(String.format("曝光成功：%s", platform.getId()));
                    onAdShowSafety();
                    ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, FeedAdLoader.super.posId));
                }

            });
            ad.load();
        }
    }

    protected void show(BaseAd ad) {
        AdPlaceWebConfigureVO config = ad.getConfig();
        AdPlatformEnum platform = config.getPlatform();
        String posId = config.getPositionId();
        List<SingleFeedAd> list = (List<SingleFeedAd>) ad.getAd();

        if (platform == AdPlatformEnum.PLATFORM_CSJ) {//穿山甲
            for (SingleFeedAd item : list) {
                TTNativeExpressAd adThird = (TTNativeExpressAd) item.getAd();
                //设置交互事件
                adThird.setExpressInteractionListener(new TTNativeExpressAd.ExpressAdInteractionListener() {
                    public void onAdShow(View view, int type) {
                        onAdShowSafety();
                    }

                    public void onRenderSuccess(View view, float width, float height) {
                        Log.dp(String.format("曝光成功：%s", platform.getId()));
                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, FeedAdLoader.super.posId));
                    }

                    public void onAdClicked(View view, int type) {
                        getAdListener().onAdClick(item);

                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, FeedAdLoader.super.posId));
                    }

                    public void onRenderFail(View view, String msg, int code) {
                        Log.e(GsonUtils.gsonString(AdError.build(platform, adType, code, msg)));
                        onAdShowErrorSafety(AdError.build(platform, adType, code, msg), platform, false);
                    }
                });
                adThird.setDislikeCallback(context, new TTAdDislike.DislikeInteractionCallback() {
                    public void onShow() {
                        getAdListener().onDislikeShow();
                    }

                    public void onSelected(int position, String value, boolean enforce) {
//                        View adView = adThird.getExpressAdView();
//                        ((ViewGroup) adView.getParent()).removeView(adView);
                        getAdListener().onDislikeSelected(item, value);
                    }

                    public void onCancel() {
                        getAdListener().onDislikeDismiss();
                    }
                });
            }
            getAdListener().onAdReadyShow(list);
        } else if (platform == AdPlatformEnum.PLATFORM_YLH) {//优量汇
            getAdListener().onAdReadyShow(list);
        } else if (platform == AdPlatformEnum.PLATFORM_KS) {//快手联盟
            for (SingleFeedAd item : list) {
                KsFeedAd adThird = (KsFeedAd) item.getAd();
                KsAdVideoPlayConfig videoPlayConfig = new KsAdVideoPlayConfig.Builder()
                        .videoSoundEnable(!autoPlayMuted)//声音策略
                        .dataFlowAutoStart(true)//非WiFi环境下的声音策略
                        .build();
                adThird.setVideoPlayConfig(videoPlayConfig);
                //设置交互事件
                adThird.setAdInteractionListener(new KsFeedAd.AdInteractionListener() {
                    public void onAdShow() {
                        Log.dp(String.format("曝光成功：%s", platform.getId()));
                        onAdShowSafety();
                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_EXPOSURE, FeedAdLoader.super.posId));
                    }

                    public void onAdClicked() {
                        getAdListener().onAdClick(item);

                        ApiServiceImpl.addTrack(UserBehaviorAddDTO.build(config, AdEventSign.AD_CLICK, FeedAdLoader.super.posId));
                    }

                    public void onDislikeClicked() {
                        getAdListener().onDislikeShow();
                    }

                    public void onDownloadTipsDialogShow() {

                    }

                    public void onDownloadTipsDialogDismiss() {

                    }
                });
            }
            getAdListener().onAdReadyShow(list);
        } else if (platform == AdPlatformEnum.PLATFORM_MINTEGRAL) {
            getAdListener().onAdReadyShow(list);
        }
    }

    /**
     * 设置声音策略<br/>
     */
    public void setAutoPlayMuted(boolean autoPlayMuted) {
        this.autoPlayMuted = autoPlayMuted;
    }
}
